#pragma once

#if defined(_WIN32) || defined(_WIN64)
#include "Windows/DLLoader.h"
#else
#include "Unix/DLLoader.h"
#endif

#include <memory>
#include <string>

namespace dlloader
{
    class IDLLoader
    {
    private:
        IDLLoader()
        {
            __dllloader = std::make_shared<DLLoader>();
        };

        ~IDLLoader(){};

    private:
        void closeLib()
        {
            __dllloader->closeLib();
        }

        std::shared_ptr<DLLoader> __dllloader;

    public:
        static std::shared_ptr<IDLLoader> create()
        {
            return std::shared_ptr<IDLLoader>(new IDLLoader,  [](IDLLoader* ptr){
                    if(ptr)
                    {
                        ptr->closeLib();
                        delete ptr;
                    }
                });
        }

        int openLib(const std::string &pathToLib)
        {
            return __dllloader->openLib(pathToLib);
        }

        template <class T>
        std::shared_ptr<T> getClassInstance()
        {
            return __dllloader->getClassInstance<T>();
        };

        template <class T>
        std::shared_ptr<T> getFuncInstance(const std::string &func_name)
        {
            return __dllloader->getFuncInstance<T>(func_name);
        };
    };
}